#if !defined(_AWORLD_H_)
#define _AWORLD_H_

#include "AObject.h"
#include "AEvent.h"

class CAStage;
class CAStageLayer;
class CASprite;
class CAXMLNode;
class CAUserData;

class CAWorld : public CAObject
{
protected:
	static CAWorld* sm_pSharedWorld;

	CAUserData* _pUserData;

	CAStage* _currentStage;
	float _volumeMusic;
	float _volumeSound;

	void _setFPS(float fps);

	class CAFadeRecord : public CAObject
	{
	public:
		CAFadeRecord() { autorelease(); }

		CAString from;
		CAString to;
		float duration;
		CAString trans;
	};
	CAStringMap<CAFadeRecord>* _pFadeTable;

	void _loadSettings(CAXMLNode* pnode);
	void _loadFadeTable(CAXMLNode* pnode);
public:
	CAWorld(void);
	virtual ~CAWorld(void);
public:
	static CAWorld& sharedWorld() { return *sm_pSharedWorld; }
	
	virtual CAStage* getCurrentStage() { return _currentStage; }
	virtual CAStage* createStage(const char* name) = 0;
	virtual CAStageLayer* createLayer(CAStage* pstage, CAStageLayer* playerParent, const char* name) = 0;
	virtual CASprite* createSprite(CAStageLayer* player, const char* name) = 0;

	void dispatchEvent(ESystemEvent evt, void* data = null);

	void switchStage(CAStage* pstage);

	static CCSize getScreenSize();

	float getMusicVolume() const { return _volumeMusic; }
	float getSoundVolume() const { return _volumeSound; }

	void setMusicVolume(float v) { _volumeMusic = v; }
	void setSoundVolume(float v) { _volumeSound = v; }

	static void percent2view(CCPoint& pos)
	{ 
		CCSize s = getScreenSize();
		pos.x *= s.width;
		pos.y *= s.height;
	}

	static void percent2view(CCSize& size)
	{
		CCSize s = getScreenSize();
		size.width *= s.width, 
		size.height *= s.height;
	}

	static void percent2view(CCRect& rect)
	{
		CCSize s = getScreenSize();
		rect.origin.x *= s.width;
		rect.origin.y *= s.height;
		rect.size.width *= s.width;
		rect.size.height *= s.height;
	}

	static void percent2view(float& v, bool bx)
	{
		CCSize s = getScreenSize();
		if (bx) v *= s.width;
		else v *= s.height;
	}

	static CCSpriteFrame* spriteFrameByName(const char* name)
	{
		return CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(name);
	}
	static CCAnimation* animationByName(const char* name)
	{
		return CCAnimationCache::sharedAnimationCache()->animationByName(name);
	}
#if defined(_CC_OLD_)
	static CCMutableArray<CCSpriteFrame*>* framesByAnimationName(const char* name)
	{
		return CCAnimationCache::sharedAnimationCache()->animationByName(name)->getFrames();
	}
#else
	static CCArray* framesByAnimationName(const char* name)
	{
		return CCAnimationCache::sharedAnimationCache()->animationByName(name)->getFrames();
	}
#endif

	virtual int initialize();
};

#endif //_AWORLD_H_